<?php


namespace App\Http\Middleware;

use App\Helpers\Jwt;
use App\Helpers\JwtUtils;
use App\Services\MenuService;
use Closure;
use Illuminate\Http\Request;
use Illuminate\Support\Str;

class CheckAuth
{
    /**
     * Handle an incoming request.
     *
     * @param \Illuminate\Http\Request $request
     * @param \Closure $next
     * @return mixed
     */
    public function handle(Request $request, Closure $next)
    {
        // 验证访问权限
        $action = app('request')->route()->getAction();
        $controller = class_basename($action['controller']);
        list($controller, $action) = explode('@', $controller);

        // 排除无需验证的控制器
        $noLoginActs = ['LoginController', 'IndexController'];
        if (!in_array($controller, $noLoginActs)) {
            // 控制器名
            $controller = strtolower(str_replace("Controller", null, $controller));
            $permission = "sys:{$controller}:{$action}";

            // 获取用户ID
            $userId = JwtUtils::getUserId();
            if ($userId != 1 && $userId != 27) {
                // 权限节点列表
                $menuService = new MenuService();
                $permissionList = $menuService->getPermissionsList($userId);
                if ($this->checkSingleMenu($permission, $permissionList)) {
                    return $next($request);
                }
                // 退出登录， 跳过验证
                $passPermission = [
                    'sys:user:logout',
                    'sys:itemcate:getCateList',
                    'sys:item:getItemList'
                ];
                if (in_array($permission, $passPermission)) {
                    return $next($request);
                }
                if (!in_array($permission, $permissionList)) {
                    return response()->json(message("暂无权限", false, null, 403));
                }
            }
        }
        return $next($request);
    }

    /**
     * 检查单一权限，系统自带的会加上 :index 导致权限无效, 需要去掉 :index, 自己加上后缀(allot, accept)，类似情况很多，无法直接去权限处添加
     * 用 ":" 分隔的数组，如果有三个，表示是自己设置的，无需系统添加后缀
     *
     * @param $permission
     * @param $permissionList
     */
    private function checkSingleMenu($permission, $permissionList)
    {
        $permissionArr = explode(':', $permission);
        if (count($permissionArr) < 3) {
            return false;
        }
        foreach ($permissionList as $item) {
            $itemArr = explode(':', $item);
            if (count($itemArr) < 4) {
                continue;
            }
            $item = implode(':', array_slice($itemArr, 0, -1));
            if ($item == $permission) {
                return true;
            }
        }
        return false;
    }
}
